package com.glacier.yuyuan.modules.admin.sys.service.impl;

import cn.hutool.core.util.StrUtil;
import com.glacier.common.support.service.impl.BaseServiceImpl;
import com.glacier.yuyuan.common.constant.DataScopeConstants;
import com.glacier.yuyuan.modules.admin.sys.domain.Role;
import com.glacier.yuyuan.modules.admin.sys.domain.RoleMenu;
import com.glacier.yuyuan.modules.admin.sys.domain.RoleOffice;
import com.glacier.yuyuan.modules.admin.sys.mapper.RoleMapper;
import com.glacier.yuyuan.modules.admin.sys.mapper.RoleMenuMapper;
import com.glacier.yuyuan.modules.admin.sys.mapper.RoleOfficeMapper;
import com.glacier.yuyuan.modules.admin.sys.mapper.UserRoleMapper;
import com.glacier.yuyuan.modules.admin.sys.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

/**
 * date 2022-11-13 12:36
 * 角色业务类
 *
 * @author glacier
 * @version 1.0
 */
@Transactional(readOnly = true)
@Service
public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, Role> implements RoleService {

    private RoleMenuMapper roleMenuMapper;

    private RoleOfficeMapper roleOfficeMapper;

    private UserRoleMapper userRoleMapper;

    public RoleServiceImpl() {
        super(RoleMapper.class);
    }

    @Autowired
    public void setRoleMenuMapper(RoleMenuMapper roleMenuMapper) {
        this.roleMenuMapper = roleMenuMapper;
    }

    @Autowired
    public void setRoleOfficeMapper(RoleOfficeMapper roleOfficeMapper) {
        this.roleOfficeMapper = roleOfficeMapper;
    }

    @Autowired
    public void setUserRoleMapper(UserRoleMapper userRoleMapper) {
        this.userRoleMapper = userRoleMapper;
    }

    /**
     * 查询
     *
     * @param id
     * @return
     */
    @Override
    public <ID extends Serializable> Role findById(ID id) {
        Role entity = super.findById(id);
        entity.setMenuIdList(roleMenuMapper.findListByRoleId(id));
        entity.setOfficeIdList(roleOfficeMapper.findListByRoleId(id));
        return entity;
    }

    /**
     * 保存
     *
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int save(Role entity) {
        int update = super.save(entity);
        if (!entity.isNewRecordFlag()) {
            // 删除菜单和角色关系
            roleMenuMapper.deleteByRoleIds(List.of(entity.getId()));

            // 删除机构和角色关系
            roleOfficeMapper.deleteByRoleIds(List.of(entity.getId()));
        }

        // 保存新的菜单和角色关系
        if (!entity.getMenuIdList().isEmpty()) {
            roleMenuMapper.batchInsert(
                entity.getMenuIdList()
                    .stream()
                    .map(menuId -> new RoleMenu(entity.getId(), menuId))
                    .collect(Collectors.toSet()));
        }

        // 保存新的机构和角色关系
        if (StrUtil.equals(entity.getDataScope(), DataScopeConstants.DATA_SCOPE_CUSTOM)
            && !entity.getOfficeIdList().isEmpty()) {
            roleOfficeMapper.batchInsert(
                entity.getOfficeIdList()
                    .stream()
                    .map(officeId -> new RoleOffice(entity.getId(), officeId))
                    .collect(Collectors.toSet()));
        }
        return update;
    }

    /**
     * 删除
     *
     * @param idList
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public <ID extends Serializable> int batchDelete(List<ID> idList) {
        int delete = super.batchDelete(idList);
        if (!idList.isEmpty()) {
            // 删除菜单和角色关系
            roleMenuMapper.deleteByRoleIds(idList);

            // 删除机构和角色关系
            roleOfficeMapper.deleteByRoleIds(idList);

            // 删除用户和角色关系
            userRoleMapper.deleteByRoleIds(idList);
        }
        return delete;
    }
}
